package com.guguskins.back.config;

import com.guguskins.back.common.filter.TokenAuthFilter;
import com.guguskins.back.common.filter.TokenLoginFilter;

import com.guguskins.back.common.security.utils.DefaultPasswordEncoder;
import com.guguskins.back.common.security.utils.UnAuthEntryPoint;

import com.guguskins.back.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DefaultPasswordEncoder defaultPasswordEncoder;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //异常
        http.exceptionHandling()
                .authenticationEntryPoint(new UnAuthEntryPoint());//没有权限访问

        //开启跨域 禁用CSRF
        http.cors()
                .configurationSource(corsConfigurationSource());
        http.csrf().disable();
        //其余所有请求都需要认证
        http.authorizeRequests()
                .antMatchers("/*/back/**").authenticated();
        //退出
//        http.logout().logoutUrl("/adminUser/logout")//退出路径
//                .addLogoutHandler(new TokenLogoutHandler(redisUtil));
        //过滤器
        http.addFilter(new TokenLoginFilter(authenticationManager(), redisUtil))
                .addFilter(new TokenAuthFilter(authenticationManager(), redisUtil)).httpBasic();
    }

    //调用userDetailsService和密码处理
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
//        auth.userDetailsService(userDetailsService).passwordEncoder(defaultPasswordEncoder);
    }

    private AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setHideUserNotFoundExceptions(false);
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(defaultPasswordEncoder);
        return provider;
    }

    private CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");    //同源配置，*表示任何请求都视为同源，若需指定ip和端口可以改为如“localhost：8080”，多个以“，”分隔；
        corsConfiguration.addAllowedHeader("*");    //header，允许哪些header，本案中使用的是token，此处可将*替换为token；
        corsConfiguration.addAllowedMethod("*");    //允许的请求方法，PSOT、GET等
        // source.registerCorsConfiguration("/adminUser/back-accessToken", corsConfiguration); //配置允许跨域访问的url
        source.registerCorsConfiguration("/**", corsConfiguration); //配置允许跨域访问的url
        return source;
    }

    //不进行认证的路径，可以直接访问
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/user/back/login",
                "/test/**"
        );
    }

}
